﻿Imports System.ComponentModel
Imports Mysoft.Map.Data
Imports System.Xml
Imports System.IO
Imports System.Text
Imports System.Web.Caching
Imports System.Web
Imports System.Xml.Xsl
Imports System.Web.UI.WebControls
Imports System.Web.UI
Imports System.Text.RegularExpressions


Namespace Control
    <DefaultProperty("SettingName"), ToolboxData("<{0}:GridTree runat=""server""></{0}:GridTree>")> _
    Public Class GridTree
        Inherits WebControl

        ''' <summary>
        ''' SQL自定义过滤字段
        ''' </summary>
        ''' <remarks></remarks>
        Private _customFilter As String = "(2=2)"
        Private _levelCell As String
        Private _parentCell As String
        Private _ifEndCell As String
        Private _rootParentValue As String
        Private _selectCell As XmlNodeList
        Private _orderby As String   '排序字段
        Private _iconCell As XmlNode
        Private _sqlString As String
        Private _rowAttrCell As XmlNodeList
        Private _rowEvent As XmlAttributeCollection

        Public Property CustomFilter() As String
            Get
                Return _customFilter
            End Get
            Set(ByVal value As String)
                _customFilter = value
            End Set
        End Property


        Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
            Dim HTML = New StringBuilder()
            Dim pagexml = HttpContext.Current.Request.Path.Replace(".aspx", ".xml")
            Dim xml = New XmlDocument()
            Dim xmlpath = HttpContext.Current.Server.MapPath(pagexml)
            Dim SqlString = ""
            If File.Exists(xmlpath) Then
                xml = EKPCache.GetXmlFile(xmlpath)
                Dim gridTree = xml.SelectSingleNode("/page/controls/control[@id='" + Me.ID + "']")
                SqlString = gridTree.SelectSingleNode("datasource/sql").InnerXml
                SqlString = SqlString.Replace("(2=2)", _customFilter)
                Dim re As New Regex("ORDER BY.*", RegexOptions.IgnoreCase)
                Dim hasorderby = re.Match(SqlString)
                If (hasorderby.Length > 0) Then
                    _orderby = hasorderby.Value
                End If

                _sqlString = re.Replace(SqlString, "")

                _levelCell = gridTree.SelectSingleNode("gridtree/levelCell").InnerXml
                _parentCell = gridTree.SelectSingleNode("gridtree/parentCell").InnerXml
                '生成标题
                HTML.Append("<table width='100%' height='100%' cellspacing='0' cellpadding='0' border='0'>")
                If gridTree.SelectSingleNode("gridtree/titles") IsNot Nothing Then
                    HTML.Append(" <tr><td height='21px'><table class='gridtree_title' border='0'  width='100%' cellspacing='0' cellpadding='0'>")
                    HTML.Append(gridTree.SelectSingleNode("gridtree/titles").InnerXml)
                    HTML.Append("</table></td></tr>")
                End If

                HTML.Append("<tr><td><div id='gridtree_container'>")

                _rootParentValue = gridTree.SelectSingleNode("gridtree/rootParentValue").InnerXml
                '添加根层级

                Dim SQL = String.Format("select * from ({0}) as aa where {1}='#parentValue#' order by {2}", _sqlString, _parentCell, _levelCell)
                HTML.Append(GetChildNodes(_rootParentValue, Me.ID, xmlpath, SQL.Replace("#parentValue#", _rootParentValue), True))

                HTML.AppendFormat("</div></td></tr></table><script type='text/javascript'>option.treeId='{1}';option.xmlpath='{2}';$('#gridtree_container').find('table').click(function(){3});var {4}={5}</script><script id='sqlstring' type='text/html'>{0}</script>", SQL, Me.ID, HttpContext.Current.Server.UrlEncode(xmlpath), "{$('.gridtree_selected').removeClass('gridtree_selected');$(this).addClass('gridtree_selected')}", Me.ID, "{expandNode:function(node){gridtree_ec(node,'load')},selectRow:function(node){selectRow(this,node)},refreshNode:function(node){refreshNode(this,node)}}")
                writer.Write(HTML.ToString())
            Else
                writer.Write("没有找到该页面得配置文件!")
            End If
        End Sub

        Public Function GetChildNodes(ByVal pid As String, ByVal treeId As String, ByVal xmlpath As String, ByVal sql As String, ByVal isRoot As Boolean) As String

            Dim i As Integer
            Dim HTML = New StringBuilder()
            Dim xml = New XmlDocument()
            xml = EKPCache.GetXmlFile(xmlpath)
            Dim gridTree = xml.SelectSingleNode("/page/controls/control[@id='" + treeId + "']")
            Dim dateTable = MyDB.GetDataTable(sql), _levelCell = "", _parentCell = "", _selectCell As XmlNodeList, _iconField = "", _iconNode As XmlNode, _rowEvent As XmlAttributeCollection
            _levelCell = gridTree.SelectSingleNode("gridtree/levelCell").InnerXml
            _parentCell = gridTree.SelectSingleNode("gridtree/parentCell").InnerXml
            If Not gridTree.SelectSingleNode("gridtree/ifEndCell") Is Nothing Then
                _ifEndCell = gridTree.SelectSingleNode("gridtree/ifEndCell").InnerXml
            Else
                _ifEndCell = ""
            End If
            _selectCell = gridTree.SelectNodes("gridtree/row/cell")
            Dim _iconCell As XmlNode = gridTree.SelectSingleNode("gridtree/icons")
            If _iconCell IsNot Nothing Then
                _iconField = _iconCell.Attributes("field").Value
            End If
            Dim _rowAttrCell As XmlNodeList = gridTree.SelectNodes("gridtree/row/attributes/attribute")
            _rowEvent = gridTree.SelectSingleNode("gridtree/row").Attributes
            For Each row As DataRow In dateTable.Rows
                HTML.AppendFormat("<div id='{0}' {1}><table  width='100%' cellspacing='0' cellpadding='0'  border='0' ", row(_levelCell).ToString(), IIf(isRoot, "", "style='display:none'"))
                '添加行属性
                For Each rowAttr As XmlNode In _rowAttrCell
                    HTML.AppendFormat(" {0}='{1}' ", rowAttr.Attributes("name").Value, row(rowAttr.Attributes("field").Value).ToString())
                Next
                '添加行事件
                Dim hasClickAttr As Boolean = False
                For Each rowAttr As XmlAttribute In _rowEvent
                    If rowAttr.Name.ToLower() = "onclick" Then
                        hasClickAttr = True
                        HTML.Append(rowAttr.Name + "='" + treeId + ".selectedRow=this;" + rowAttr.Value + "' ")
                    Else
                        HTML.Append(rowAttr.Name + "='" + treeId + ".selectedRow=this;if(event.srcElement.tagName!=""U""){" + rowAttr.Value + "}' ")
                    End If
                Next
                If Not hasClickAttr Then
                    HTML.Append(" onclick='" + treeId + ".selectedRow=this;'")
                End If
                HTML.AppendFormat(" class='gridtree_node'><tr>")
                For i = 0 To _selectCell.Count - 1
                    HTML.AppendFormat("<td ")
                    If (_selectCell(i).Attributes("width") IsNot Nothing) Then
                        HTML.AppendFormat("width='{0}' ", _selectCell(i).Attributes("width").Value)
                    End If
                    For Each attr As XmlNode In _selectCell(i).SelectNodes("attribute")
                        HTML.AppendFormat("{0}='{1}' ", attr.Attributes(0).Name, attr.Attributes(0).Value)
                    Next
                    HTML.Append(">")
                    If i = 0 Then
                        If _ifEndCell <> "" Then
                            Dim sClass As String
                            If row(_ifEndCell).ToString() = "1" Then
                                sClass = "noimg"
                            Else
                                sClass = "collapse"
                            End If
                            HTML.AppendFormat("<u class='{0}' onclick='gridtree_ec(""{1}"")'></u>", sClass, row(_levelCell).ToString())
                        Else
                            HTML.AppendFormat("<u class='collapse' onclick='gridtree_ec(""{0}"")'></u>", row(_levelCell).ToString())
                        End If

                        '判断是否需要添加图标
                        If _iconCell IsNot Nothing Then
                            _iconNode = _iconCell.SelectSingleNode("icon[@value='" + row(_iconField).ToString() + "']")
                            If _iconNode.InnerXml.Trim() <> "" Then
                                HTML.AppendFormat("&nbsp;<span style='background:url({0}); width:16px;height:16px' title='{1}'></span>", _iconNode.InnerXml, _iconNode.Attributes("desc").Value)
                            End If
                        End If
                    End If
                    HTML.AppendFormat("<span class='gridText'>{0}</span></td>", row(_selectCell(i).Attributes("field").Value).ToString())
                Next
                HTML.Append("</tr></table></div>")
            Next
            Return HTML.ToString()
        End Function
    End Class
    Public Class EKPCache
        ''' <summary>
        ''' 获取缓存的XML文件
        ''' </summary>
        ''' <param name="url">XML文件相对地址</param>
        ''' <returns>缓存后的XML文件</returns>
        ''' <remarks></remarks>
        Public Shared Function GetXmlFile(ByVal url As String) As XmlDocument
            Dim document As XmlDocument
            Try
                Dim key As String = url
                document = DirectCast(Mysoft.Map.Caching.MyCache.Get(key), XmlDocument)
                If document Is Nothing Then
                    document = New XmlDocument
                    Dim filename As String = HttpContext.Current.Server.MapPath(url)
                    document.Load(filename)
                    Mysoft.Map.Caching.MyCache.Insert(key, document, New CacheDependency(filename))
                End If
                Return document
            Catch ex As Exception
                Return Nothing
            End Try
        End Function

    End Class
End Namespace
